package cn.jane.rpc.netty.client.impl;

import static cn.jane.rpc.netty.util.FileUtil.readResourceToString;

import cn.jane.rpc.netty.client.ServiceStub;
import cn.jane.rpc.netty.client.StubFactory;
import cn.jane.rpc.netty.transport.Transport;
import com.itranswarp.compiler.JavaStringCompiler;
import java.util.Map;

/**
 * 动态桩工厂
 */
public class DynamicStubFactory implements StubFactory {

    private static final String STUB_SOURCE_TEMPLATE;

    static {
        STUB_SOURCE_TEMPLATE = readResourceToString("stub.template");
    }

    @Override
    public <T> T createStub(Transport transport, Class<T> serviceClass) {
        try {
            // 填充代码模板
            String stubSimpleName = serviceClass.getSimpleName() + "Stub";
            String classFullName = serviceClass.getName();
            String stubFullName = "cn.jane.rpc.netty.client.stubs." + stubSimpleName;
            // TODO 这里只会获取指定类的第一个方法
            String methodName = serviceClass.getMethods()[0].getName();
            String source = String.format(STUB_SOURCE_TEMPLATE,
                    stubSimpleName, classFullName, methodName, classFullName, methodName);

            // 编译源代码
            JavaStringCompiler compiler = new JavaStringCompiler();
            Map<String, byte[]> results = compiler.compile(stubSimpleName + ".java", source);

            // 加载编译好的类
            Class<?> clazz = compiler.loadClass(stubFullName, results);

            // 把 Transport 赋值给桩
            ServiceStub stubInstance = (ServiceStub) clazz.newInstance();
            stubInstance.setTransport(transport);
            // 返回这个桩
            return (T) stubInstance;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }
    }
}
